<?php
/*
 * @copyright: 有酱料
 * @author: Xinpow<xinpow@live.com>
 * @lang: zh_CN
 * @version: v1.0
 */
namespace Xinpow\Esign;

use Xinpow\Esign\Core\BaseHelper;
use Xinpow\Esign\ErrorCode;
use Xinpow\Esign\Core\InitClient;
use Xinpow\Esign\Core\CreateAccount;
use Xinpow\Esign\Core\CreateSeal;
use Xinpow\Esign\Core\CreateSign;

class Factory {

    use BaseHelper {
        BaseHelper::__construct as private _traitContruct;
    }

    public function __construct(){
        $this->_traitContruct();
    }

    /**
     * 初始化 SDK
     */
    public function init() {
        if(!$this->_config->app_id) {
            return $this->fail(ErrorCode::$error['NO_APP_ID']);
        }
        if(!$this->_config->app_secret) {
            return $this->fail(ErrorCode::$error['NO_APP_SECRET']);
        }
        $init = InitClient::handle();
        return $this->reject($init->doRegister(), '初始化数据失败');
    }

    /**
     * 创建签署账号
     *
     * @param string $accountType 账号类型：个人（personal）、企业（business）
     * @param array  $data 注册数据
     *                  $accountType === personal ?
     *                      email  : 注册电子邮箱
     *                      mobile : 注册手机号码
     *                      name   : 注册用户名
     *                      idNo   : 身份证号码
     *                  :
     *                      name      : 企业名称
     *                      regType   : 执照类型，NORMAL（组织机构代码）、MERGE（社会信用代码）、REGCODE（工商注册号）
     *                      organCode : 组织机构代码、工商注册号或者统一社会信用代码
     */
    public function registerAccount($data, $accountType = 'personal') {
        $account = CreateAccount::handle();
        return $this->reject($account->register($data, $accountType), '注册失败');
    }

    /**
     * 更新签署账号
     *
     * @param string  $accountType 账号类型：个人（personal）、企业（business）
     * @param integer $accountId   签署者 ID
     * @param array   $data 注册数据
     *                  $accountType === personal ?
     *                      email   : 电子邮箱
     *                      mobile  : 手机号码
     *                      name    : 用户名
     *                      organ   : 所属公司
     *                      address : 常用地址
     *                      title   : 职位
     *                  :
     *                      email     : 电子邮箱
     *                      mobile    : 手机号码
     *                      name      : 企业名称
     *                      address   : 企业地址
     *                      organType : 单位类型，默认：0，Nomal（普通企业）、Sociogroup（社会团体）、Institution（事业单位）、PrivateUnit（民办非企业单位）、OrganOfState（党政及国家机构）
     *                      userType  : 执照类型，默认：DEFAULT，AGENT（代理人注册）、LEGAL（法人注册）、DEFAULT（缺省注册）
     *                      legalName : 法人名称
     *                      legalIdNo : 法人身份证/护照
     *                      scope     : 经营范围
     */
    public function updateAccount($accountId, $data, $accountType = 'personal') {
        $account = CreateAccount::handle();
        return $this->reject($account->update($accountId, $data, $accountType), '更新失败');
    }

    /**
     * 通过证件号获取账号信息
     *
     * @param string  $idNo 用户证件号
     * @param integer $type 证件类型：11:大陆身份证号、12:香港通行证、13:澳门通行证、14:台湾通行证、15:外籍证件、21:组织机构代码号、22:统一社会信用代码、23:工商注册号
     */
    public function getAccount($idNo, $type) {
        $account = CreateAccount::handle();
        return $this->reject($account->getUser($idNo, $type), '获取失败');
    }

    /**
     * 注销签署账号
     *
     * @param integer $accountId   签署者 ID
     */
    public function deleteAccount($accountId) {
        $account = CreateAccount::handle();
        return $this->reject($account->delete($accountId), '注销失败');
    }

    /**
     * 创建印章
     *
     * @param string $data 印章数据,包含字段如下:
     *                          * accountId     必填字段, 签章账号 ID
     *                            color         印章颜色
     *                            templateType  印章模版类型, 个人签章可选: SQUARE（正方形），RECTANGLE（长方形），BORDERLESS（无框矩形）
     *                                                       企业签章可选：STAR（标准公章），OVAL（椭圆形印章
     *                            hText         生成印章中的横向文内容；可设置0-8个字，企业名称超出25个字后，不支持设置横向文；一般是指的XX专用章，如合同专用章、财务专用章等
     *                            qText         生成印章中的下弦文内容；可设置0-20个字，企业企业名称超出25个字后，不支持设置下弦文；下弦文是指的贵司公章底部一串防伪数字，若没有该参数可不填
     * @param string $accountType 印章类型：个人（personal）、企业（business）
     *
     * @return object
     */
    public function createSeal($data, $accountType = 'personal') {
        $seal = CreateSeal::handle();
        return $this->reject($seal->registerSeal($data, $accountType), '印章创建失败');
    }

    /**
     * 摘要签署（平台）
     * 处理流程为从远程读取源文件后在集群内签署并返回流数据.
     *
     * @param string  $sourceFile 远程的源文件读取地址，需要能被链接访问
     *
     * @param array   $base      基础信息，具体元素如下
     *                                  {string}   ownerPassword  文档密码，当目标 PDF 设置权限保护的时候必填
     *                                  {string}   signType       签章类型，Single（单页签章）、Multi（多页签章）、Edges（签骑缝章）、Key（关键字签章）
     *                                  {string}   sealId         印章 ID，默认为0，即默认印章
     *
     * @param array   $sign_pos  签章数据，具体元素：
     *                                      posType         定位类型，0坐标定位，1关键字定位，默认0（若为关键字定位，签章类型（signType）必须指定为关键字定位才生效）
     *                                      posPage         签署页码,
     *                                      posX            签署位置X坐标,原点为左下角
     *                                      posY            签署位置Y坐标,原点为左下角
     *                                      width           签章宽度
     *                                      key             关键字，关键字签章必填
     *                                      addSignTime     是否显示本地签署时间（需要width设置92以上才可以看到时间）
     *                                      qrcodeSign      是否是二维码签署，默认为false，二维码签署不支持骑缝签和多页签
     *                                      cacellingSign   是否是作废签签署，默认为false
     *
     * @return object
     */
    public function selfSign($sourceFile, $base, $sign_pos = []) {
        $sign = CreateSign::handle();
        return $this->reject($sign->signForSelf($sourceFile, $base, $sign_pos), '签署失败');
    }

    /**
     * 摘要签署（用户）
     * 处理流程为从远程读取源文件后在集群内签署并返回流数据
     *
     * @param string  $sourceFile 远程的源文件读取地址，需要能被链接访问
     *
     * @param array   $base      基础信息，具体元素如下
     *                                  {string}   ownerPassword  文档密码，当目标 PDF 设置权限保护的时候必填
     *                                  {integer}  accountId      签署账号 ID
     *                                  {string}   sealData       印章图片 base64 数据
     *                                  {string}   mobile         接收验证码的手机
     *                                  {string}   code           短信验证码
     *                                  {string}   signType       签章类型，Single（单页签章）、Multi（多页签章）、Edges（签骑缝章）、Key（关键字签章）
     *
     * @param array   $sign_pos  签章数据，具体元素：
     *                                      posType         定位类型，0坐标定位，1关键字定位，默认0（若为关键字定位，签章类型（signType）必须指定为关键字定位才生效）
     *                                      posPage         签署页码,
     *                                      posX            签署位置X坐标,原点为左下角
     *                                      posY            签署位置Y坐标,原点为左下角
     *                                      width           签章宽度
     *                                      key             关键字，关键字签章必填
     *                                      addSignTime     是否显示本地签署时间（需要width设置92以上才可以看到时间）
     *                                      qrcodeSign      是否是二维码签署，默认为false，二维码签署不支持骑缝签和多页签
     *                                      cacellingSign   是否是作废签签署，默认为false
     */
    public function otherSign($sourceFile, $base, $sign_pos = []) {
        $sign = CreateSign::handle();
        return $this->reject($sign->signForOther($sourceFile, $base, $sign_pos), '签署失败');
    }

    /**
     * 平台用户PDF摘要签署（文件流）
     * 处理流程为从远程读取源文件后在集群内签署并返回流数据
     *
     * @param string  $sourceFile 远程的源文件读取地址，需要能被链接访问
     *
     * @param array   $base      基础信息，具体元素如下
     *                                  {string}   ownerPassword  文档密码，当目标 PDF 设置权限保护的时候必填
     *                                  {integer}  accountId      签署账号 ID
     *                                  {string}   sealData       印章图片 base64 数据
     *                                  {string}   signType       签章类型，Single（单页签章）、Multi（多页签章）、Edges（签骑缝章）、Key（关键字签章）
     *
     * @param array   $sign_pos  签章数据，具体元素：
     *                                      posType         定位类型，0坐标定位，1关键字定位，默认0（若为关键字定位，签章类型（signType）必须指定为关键字定位才生效）
     *                                      posPage         签署页码,
     *                                      posX            签署位置X坐标,原点为左下角
     *                                      posY            签署位置Y坐标,原点为左下角
     *                                      width           签章宽度
     *                                      key             关键字，关键字签章必填
     *                                      addSignTime     是否显示本地签署时间（需要width设置92以上才可以看到时间）
     *                                      qrcodeSign      是否是二维码签署，默认为false，二维码签署不支持骑缝签和多页签
     *                                      cacellingSign   是否是作废签签署，默认为false
     */
    public function userSign($sourceFile, $base, $sign_pos = []) {
        $sign = CreateSign::handle();
        return $this->reject($sign->signForUser($sourceFile, $base, $sign_pos), '签署失败');
    }

    /**
     * 文档验签
     *
     * @param file $fileStream 需要验签的文件流数据
     */
    public function verify($fileStream) {
        $verify = CreateSign::handle();
        return $this->reject($verify->doVerify($fileStream), '验签失败');
    }

}
